﻿using System;
using System.Collections;

namespace ThreadSafeControls {
    partial class ThreadSafeListBox<TListBox> {
        public class SelectedObjectCollection : IList {

            private readonly ThreadSafeListBox<TListBox> _listBox;
            private object _syncRoot;

            internal SelectedObjectCollection(ThreadSafeListBox<TListBox> listBox) {
                if (listBox == null)
                    throw new ArgumentNullException("listBox");

                _listBox = listBox;
            }

            public IList Synchronize() {
                return new SynchronizedObjectCollection(this);
            }

            public object this[int index] {
                get { return _listBox.ReturnAsync(c => c.SelectedItems[index]); }
            }

            public int Count {
                get { return _listBox.ReturnAsync(c => c.SelectedItems.Count); }
            }

            public void Add(object value) {
                _listBox.UpdateAsync(c => c.SelectedItems.Add(value));
            }

            public void Clear() {
                _listBox.UpdateAsync(c => c.SelectedItems.Clear());
            }

            public bool Contains(object selectedObject) {
                return _listBox.ReturnAsync(c => c.SelectedItems.Contains(selectedObject));
            }

            public void CopyTo(Array destination, int index) {
                _listBox.UpdateAsync(c => c.SelectedItems.CopyTo(destination, index));
            }

            public int IndexOf(object selectedObject) {
                return _listBox.ReturnAsync(c => c.SelectedItems.IndexOf(selectedObject));
            }

            public void Remove(object value) {
                _listBox.UpdateAsync(c => c.SelectedItems.Remove(value));
            }

            public IEnumerator GetEnumerator() {
                return _listBox.ReturnAsync(c => c.SelectedItems.GetEnumerator());
            }

            #region Explicit Interface Members

            bool IList.IsFixedSize {
                get { return false; }
            }

            bool IList.IsReadOnly {
                get { return false; }
            }

            bool ICollection.IsSynchronized {
                get { return false; }
            }

            object ICollection.SyncRoot {
                get { return _syncRoot ?? (_syncRoot = new object()); }
            }

            int IList.Add(object value) {
                return _listBox.ReturnAsync(c => ((IList)c.SelectedItems).Add(value));
            }

            void IList.Insert(int index, object value) {
                _listBox.UpdateAsync(c => ((IList)c.SelectedItems).Insert(index, value));
            }

            void IList.RemoveAt(int index) {
                _listBox.UpdateAsync(c => ((IList)c.SelectedItems).RemoveAt(index));
            }

            object IList.this[int index] {
                get { return _listBox.ReturnAsync(c => ((IList)c.SelectedItems)[index]); }
                set { _listBox.UpdateAsync(c => ((IList)c.SelectedItems)[index] = value); }
            }

            #endregion
        }
    }
}
